-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--         http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

require 'skynet.manager'
local skynet = require 'skynet'
local sd_bus = require 'sd_bus'
local log = require 'mc.logging'
local utils = require 'mc.utils'
local test_common = require 'test_common.utils'
local mdb = require 'mc.mdb'

require 'bmc_datasync.debug.json_types.CAN'

log:setLevel(log.INFO)

local function prepare_test_data()
    log:info('prepare test data')
    local test_data_dir = skynet.getenv('TEST_DATA_DIR')
    os.execute('mkdir -p ' .. test_data_dir)

    local dir_list = {'apps/bmc_datasync/mds', 'sr', 'usr/lib64', 'data', 'apps/hwdiscovery/mds',
        'apps/frudata/mds', '/dump'}
    for _, path in pairs(dir_list) do
        os.execute('mkdir -p ' .. test_data_dir .. path)
    end
    utils.copy_file('test/integration/datatocheck_default.dat', test_data_dir .. 'datatocheck_default.dat')
    utils.copy_file('mds/schema.json', test_data_dir .. 'apps/bmc_datasync/mds/schema.json')
    utils.copy_file('mds/service.json', test_data_dir .. 'apps/bmc_datasync/mds/service.json')
    utils.copy_file('temp/usr/lib64/mock/libsoc_adapter_it.so', test_data_dir .. 'usr/lib64/libsoc_adapter.so')

    -- 拷贝依赖文件
    utils.copy_file('temp/opt/bmc/apps/hwdiscovery/mds/schema.json', test_data_dir .. '/apps/hwdiscovery/mds/schema.json')
    utils.copy_file('temp/opt/bmc/apps/frudata/mds/schema.json', test_data_dir .. '/apps/frudata/mds/schema.json')
    utils.copy_file('mds/schema.json', test_data_dir .. '/apps/bmc_datasync/mds/schema.json')
    utils.copy_file('test/integration/test_data/root.sr', test_data_dir .. '/sr/root.sr')
    utils.copy_file('test/integration/test_data/platform.sr', test_data_dir .. '/sr/platform.sr')

end

local function clear_test_data(exit_test)
    log:info('clear test data')
    local test_data_dir = skynet.getenv('TEST_DATA_DIR')
    if exit_test then
        skynet.timeout(0, function()
            skynet.sleep(20)
            skynet.abort()
            utils.remove_file(test_data_dir)
        end)
    else
        utils.remove_file(test_data_dir)
    end
end

local ready_checks = {
    {
        service = 'bmc.kepler.bmc_datasync',
        path = '/bmc/kepler/bmc_datasync/MicroComponent'
    }
}

local function wait_test_resource_is_ready(bus)
    local dbus_tool = require 'sd_bus.org_freedesktop_dbus'
    local check_ok = false
    for i = 1, 20 do
        local passed = true
        for k, v in ipairs(ready_checks) do
            local err = dbus_tool.ping(bus, v.service, v.path)
            if err then
                passed = false
                break
            end
        end

        if not passed then
            skynet.sleep(100)
        else
            log:info('wait test resource check ok, costs [%d] seconds', i - 1)
            check_ok = true
            break
        end
    end
    if not check_ok then
        error('== wait test resource timeout !!!')
    end
end

local function test_entry()
    -- setup dbus instance and wait main application to run stably
    local bus = sd_bus.open_user(true)
    wait_test_resource_is_ready(bus)
    log:info('================ test start ================')
    skynet.sleep(800)  -- 等待800用于对象注册和数据同步
    require 'test_entry'.test_entry(bus)
    log:info('================ test complete ================')
end

skynet.start(function()
    clear_test_data(false)
    prepare_test_data()
    test_common.dbus_launch()
    skynet.uniqueservice('maca/service/main')
    skynet.uniqueservice('persistence/service/main')
    skynet.uniqueservice('hwdiscovery/service/main')
    skynet.uniqueservice('frudata/service/main')
    skynet.uniqueservice('main')
    skynet.fork(function()
        local ok, err = pcall(test_entry)
        -- 注意做数据库写验证的时候，要注释掉下面一行
        clear_test_data(true)
        if not ok then
            error(err)
        end
    end)
end)
